package com.alibaba.citrus.cr.mn.order.center.facade.service.impl;

import com.alibaba.citrus.cr.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.StopWatchUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.TrimUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.covert.SalesOrderAtomQueryResponseToSalesOrderGroupQueryResponse;
import com.alibaba.citrus.cr.mn.order.center.facade.function.asynctask.AsyncTaskCreateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.AbstractOrderParamsCheckService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.CommonCheck;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.*;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ObtcSaleOrderLineIndexToResponseConvertor;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.cbtcobtcorderlineadb.service.CbtcObtcOrderLineAdbService;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.QueryOrderLineByIdListRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.QueryOrderLineByIdListResponse;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.domain.orderline.service.OrderLineService;
import com.epoch.app.crb2btradecenter.model.dto.OrderLineAdbRequest;
import com.epoch.app.crb2btradecenter.model.dto.OrderLineAdbResponse;
import com.epoch.app.crb2btradecenter.model.enums.MessageTaskTypeEnum;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.model.ObtcSaleOrderLineIndex;
import com.epoch.app.mnordercenter.model.dto.*;
import com.epoch.app.mnordercenter.orderbaserequest.*;
import com.epoch.app.mnordercenter.salesordergroup.service.SalesOrderGroupService;
import com.google.common.collect.Lists;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.mn.order.center.common.constants.RedisLockConstants.*;

/**
 * @Description
 * @Author zhangjian
 * @Date 2023/12/19 14:00
 */
@Service
@Primary
public class SalesOrderGroupServiceImpl implements SalesOrderGroupService {

    private static final Log log = Log.getLogger(SalesOrderGroupServiceImpl.class);

    @Resource
    private AsyncTaskCreateService asyncTaskCreateService;
    @Resource(name = "salesOrderGroupCreateParamsCheck")
    private AbstractOrderParamsCheckService salesOrderGroupCreateParamsCheck;
    @Resource(name = "salesOrderBizSubmitService")
    private OrderBizSubmitService salesOrderBizSubmitService;
    @Resource(name = "salesOrderGroupCloseService")
    private OrderBizCloseService salesOrderGroupCloseService;
    @Resource(name = "salesOrderAtomCancelService")
    private OrderAtomCancelService selesOrderAtomCancelService;
    @Resource(name = "salesOrderAtomQueryService")
    private OrderAtomQueryService salesOrderAtomQueryService;
    @Resource(name = "salesOrderBizUpdateService")
    private OrderBizUpdateService<OrderBizUpdateRequest, OrderAtomUpdateRequest, OrderAtomUpdateResponse> salesOrderBizUpdateService;
    @Resource(name = "salesOrderBizCreateService")
    private OrderBizCreateService<SalesOrderBizBatchCreateRequest, SalesOrderAtomBatchCreateRequest, OrderAtomCreateResponse> salesOrderBizCreateService;

    @Resource
    private SendMsgService sendMsgService;
    @Resource
    private CommonCheck commonCheck;
    @Resource
    private CbtcObtcOrderLineAdbService cbtcObtcOrderLineAdbService;
    @Resource
    private OrderLineService orderLineService;

    /**
     * 字段值如果为空，返回空字符串，而不是null。
     *
     * @param source
     * @return
     */
    private static String nvlToEmptyStr(String source) {
        if (StringUtils.isBlank(source)) {
            return "";
        }
        return source;
    }

    @FacadeInvoker(value = "一盘货销售订单批量关闭", errorCode = "OC-01-003-01-16-003")
    @Override
    public Result<List<OrderAtomCloseResponse>> batchClose(OrderBizBatchCloseRequest request) {
        log.info("SalesOrderGroupServiceImpl#batchClose request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("SalesOrderGroupServiceImpl#batchClose lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#batchClose 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
            Result<List<OrderAtomCloseResponse>> result = salesOrderGroupCloseService.batchClose(request);
            return result;
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#batchClose error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#batchClose");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单批量取消", errorCode = "OC-01-003-01-16-009")
    public Result<List<OrderAtomCancelResponse>> batchCancel(OrderAtomBatchCancelRequest request) {
        log.info("SalesOrderGroupServiceImpl#batchCancel request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("SalesOrderGroupServiceImpl#batchCancel lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#batchCancel 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            AssertUtils.isTrue(StringUtils.isBlank(request.getModifierCode()), "OC-01-001-01-15-001", "修改人工号");
            AssertUtils.lengthCheck(request.getModifierCode(), 50, true, "OC-01-001-01-15-004", "修改人工号");
            AssertUtils.isTrue(CollectionUtils.isEmpty(request.getOrderList()), "OC-01-001-01-15-001", "单据列表");
            Modifiers modifiers = commonCheck.invalidModifier(request.getModifierCode());
            request.getOrderList().forEach(order -> {
                        order.setModifierCode(modifiers.getWorkId());
                        order.setModifierName(modifiers.getName());
                    }
            );
            List<OrderAtomCancelResponse> responseList = selesOrderAtomCancelService.batchCancel(request, OrderCategoryEnum.GROUP.getCode());
            responseList.forEach(res -> {
                if (Objects.isNull(res.getSuccess())) {
                    res.setSuccess(Boolean.FALSE);
                }
            });

            List<String> salesOrderNos = responseList.stream()
                    .filter(OrderAtomCancelResponse::getSuccess)
                    .map(OrderAtomCancelResponse::getSalesOrderNo)
                    .collect(Collectors.toList());
            // 发送MQ消息通知其他中心
//            sendMsgService.sendSalesOrderChangeMsg(salesOrderNos, InnerMessageEventEnum.SALES_ORDER_UPDATED);

            return Result.success(responseList, "", "");
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#batchCancel error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#batchCancel");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单精准查询", errorCode = "OC-01-003-01-16-008")
    public Result<List<SalesOrderGroupQueryResponse>> loadListForPage(SalesOrderDetailQueryRequest request) {
        SalesOrderAtomQueryListRequest salesOrderAtomQueryListRequest = new SalesOrderAtomQueryListRequest();
        BeanUtils.copyProperties(request, salesOrderAtomQueryListRequest);
        salesOrderAtomQueryListRequest.setSalesOrderNo(StringUtils.isNotBlank(request.getSalesOrderNo()) ? Lists.newArrayList(request.getSalesOrderNo()) : null);
        salesOrderAtomQueryListRequest.setSourceOrderNo(StringUtils.isNotBlank(request.getSourceOrderNo()) ? Lists.newArrayList(request.getSourceOrderNo()) : null);
        PageResult<List<SalesOrderAtomQueryResponse>> result = salesOrderAtomQueryService.listPage(salesOrderAtomQueryListRequest, OrderCategoryEnum.GROUP.getCode());
        List<SalesOrderGroupQueryResponse> salesOrderGroupQueryResponseList = SalesOrderAtomQueryResponseToSalesOrderGroupQueryResponse.convert(result.getContent());
        Result<List<SalesOrderGroupQueryResponse>> success = Result.success(salesOrderGroupQueryResponseList, "", "");
        success.setTotal(result.getTotal());
        return success;
    }

    @FacadeInvoker(value = "一盘货销售订单批量创建", errorCode = "OC-01-001-01-16-006")
    @Override
    public Result<SalesOrderBizCreateResponse> batchCreate(SalesOrderBizBatchCreateRequest request) {
        AssertUtils.isTrue(StringUtils.isBlank(request.getReqNo()), "OC-01-001-01-15-001", "请求编码");

        log.info("SalesOrderGroupServiceImpl#batchCreate request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + request.getReqNo();
        log.info("SalesOrderGroupServiceImpl#batchCreate lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#batchCreate 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            // 移除入参里的前后空格
            StopWatchUtils.start("订单中心一盘货销售订单", "removeSpace");
            TrimUtils.removeSpace(request);
            StopWatchUtils.stop();

            StopWatchUtils.start("订单中心一盘货销售订单", "paramsInvalidCheck");
            AssertUtils.lengthCheck(request.getReqNo(), 128, true, "OC-01-001-01-15-004", "请求编码");
            AssertUtils.isTrue(CollectionUtils.isEmpty(request.getOrderList()), "OC-01-001-01-15-001", "单据列表");
            request.getOrderList().forEach(order -> {
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    order.setFromSys(request.getFromSys());
                }
                if (StringUtils.isNotBlank(request.getBusinessType())) {
                    order.setBusinessType(request.getBusinessType());
                }
                if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                    order.setBusinessUnitCode(request.getBusinessUnitCode());
                }

                if (StringUtils.isBlank(order.getFulfillmentTypeCode())) {
                    order.setFulfillmentTypeCode(FulfillmentTypeEnum.EXTERNAL_TO_EXTERNAL.getCode());
                }
                if (StringUtils.isBlank(order.getFulfillmentPriority())) {
                    order.setFulfillmentPriority(FulfillmentPriorityEnum.NORMAL.getCode());
                }
                if (StringUtils.isBlank(order.getAutoFulfillment())) {
                    order.setAutoFulfillment(Boolean.TRUE.toString());
                }
                if (Objects.isNull(order.getCheckCredit())) {
                    order.setCheckCredit(Boolean.TRUE);
                }
                if (Objects.isNull(order.getCheckStock())) {
                    order.setCheckStock(Boolean.TRUE);
                }
                if (Objects.isNull(order.getIsSubmit())) {
                    order.setIsSubmit(Boolean.TRUE);
                }
                // 设置默认值
                order.setCheckCreditB(Boolean.FALSE);
                order.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
            });
            salesOrderGroupCreateParamsCheck.paramsInvalidCheck(request.getOrderList(), new ArrayList<>());
            StopWatchUtils.stop();

            String batchTaskId = asyncTaskCreateService.createAsyncTask(request.getFromSys() + "#" + request.getReqNo(),
                    request.getFromSys(), JSON.toJSONString(request), MessageTaskTypeEnum.OC_SALES_ORDER_BATCH_CREATE);

            SalesOrderBizCreateResponse salesOrderBizCreateResponse = new SalesOrderBizCreateResponse();
            salesOrderBizCreateResponse.setBatchTaskId(batchTaskId);
            return Result.success(salesOrderBizCreateResponse, "", "");

        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#batchCreate error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#batchCreate");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单批量提交", errorCode = "OC-01-003-01-16-002")
    public Result<List<OrderAtomSubmitResponse>> batchSubmit(OrderBizBatchSubmitRequest request) {
        log.info("SalesOrderGroupServiceImpl#batchSubmit request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + DigestUtils.md5Hex(JSON.toJSONString(request));
        log.info("SalesOrderGroupServiceImpl#batchSubmit lockKey={}", lockKey);

        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#batchSubmit 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            Optional.ofNullable(request.getOrderList()).orElse(Lists.newArrayList()).forEach(salesOrder -> {
                if (Objects.isNull(salesOrder.getCheckStock())) {
                    salesOrder.setCheckStock(Boolean.TRUE);
                }
                if (Objects.isNull(salesOrder.getCheckCredit())) {
                    salesOrder.setCheckCredit(Boolean.TRUE);
                }
                salesOrder.setCheckCreditB(Boolean.FALSE);
            });
            request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());

            List<OrderAtomSubmitResponse> responses = salesOrderBizSubmitService.batchSubmit(request);

            List<String> allSalesOrderNos = request.getOrderList().stream()
                    .map(OrderAtomSubmitRequest::getSalesOrderNo)
                    .collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(responses)) {
                // 发送消息通知来源系统
                List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
                for (OrderAtomSubmitResponse submitResponse : responses) {
                    pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                            .salesOrderNo(submitResponse.getSalesOrderNo())
                            .orderStatus(SalesOrderPushStatusEnum.FAIL_UPDATE.getOrderStatusCode())
                            .message(submitResponse.getMessage())
                            .build());

                    // 移除提交失败的销售订单号
                    allSalesOrderNos.remove(submitResponse.getSalesOrderNo());
                }

                // 发送kafka消息通知应用端处理结果
                CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
                commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.SALES_ORDER_UPDATE.getValue());
                commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.SALES_ORDER_UPDATE.getLabel());
                commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
                commonAsyncMessageResponse.setFromSys(request.getFromSys());
                commonAsyncMessageResponse.setBusinessUnitCode(request.getBusinessUnitCode());
                commonAsyncMessageResponse.setData(pushOrderInfoList);
                sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
                log.info("SalesOrderGroupServiceImpl#batchSubmit sendMsgToSendKafka message={}", commonAsyncMessageResponse);
            }

            // 发送MQ消息通知其他中心
//            sendMsgService.sendSalesOrderChangeMsg(allSalesOrderNos, InnerMessageEventEnum.SALES_ORDER_SUBMITTED);
            log.info("SalesOrderGroupServiceImpl#batchSubmit responses={}", JSON.toJSONString(responses));
            if (CollectionUtils.isNotEmpty(responses)) {
                return Result.fail(responses, "", "");
            } else {
                return Result.success(responses, "", "");
            }
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#batchSubmit error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#batchSubmit");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单主单列表查询", errorCode = "OC-01-001-01-16-056")
    public Result<List<SalesOrderPageQueryResponse>> pageQuery(SalesOrderGroupPageQueryRequest request) {
        SalesOrderAtomPageQueryRequest salesOrderAtomPageQueryRequest = new SalesOrderAtomPageQueryRequest();
        BeanUtils.copyProperties(request, salesOrderAtomPageQueryRequest);
        salesOrderAtomPageQueryRequest.setSalesChannelCode(request.getSalesChannelCodeList());
        salesOrderAtomPageQueryRequest.setSalesDepartmentCode(request.getSalesDepartmentCodeList());
        salesOrderAtomPageQueryRequest.setNote(request.getNote());
        if (StringUtils.isNotBlank(request.getBusinessChannelCode())) {
            salesOrderAtomPageQueryRequest.setBusinessChannel(Lists.newArrayList(request.getBusinessChannelCode()));
        }
        if (CollectionUtils.isEmpty(request.getSalesOrderTypeList())) {
            salesOrderAtomPageQueryRequest.setSalesOrderType(SalesOrderTypeEnum.groupOrderCodes());
        } else {
            salesOrderAtomPageQueryRequest.setSalesOrderType(request.getSalesOrderTypeList());
        }
        salesOrderAtomPageQueryRequest.setOrderCategoryCodeList(Lists.newArrayList(OrderCategoryEnum.GROUP.getCode(), OrderCategoryEnum.STOCK.getCode()));
        log.info("SalesOrderGroupServiceImpl#pageQuery salesOrderAtomPageQueryRequest={}", JSON.toJSONString(salesOrderAtomPageQueryRequest));

        PageResult<List<SalesOrderAtomQueryResponse>> pageAtomResult = salesOrderAtomQueryService.page(salesOrderAtomPageQueryRequest, SetOrderTag.NORMAL, OrderCategoryEnum.GROUP.getCode());
        List<SalesOrderPageQueryResponse> responseList = pageAtomResult.getContent().stream().map(order -> {
            SalesOrderPageQueryResponse salesOrderPageQueryResponse = new SalesOrderPageQueryResponse();
            BeanUtils.copyProperties(order, salesOrderPageQueryResponse);
            if (Objects.nonNull(order.getBusinessType())) {
                salesOrderPageQueryResponse.setBusinessType(String.valueOf(order.getBusinessType()));
            } else {
                salesOrderPageQueryResponse.setBusinessType("");
            }
            salesOrderPageQueryResponse.setRelationNo(nvlToEmptyStr(order.getRelatonNo()));
            salesOrderPageQueryResponse.setStatus(nvlToEmptyStr(order.getOrderStatus()));
            return salesOrderPageQueryResponse;
        }).collect(Collectors.toList());

        Result<List<SalesOrderPageQueryResponse>> result = Result.success(responseList, "", "");
        result.setTotal(pageAtomResult.getTotal());
        return result;
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单明细批量查询", errorCode = "OC-01-003-01-16-008")
    public Result<List<PageQuerySaleOrderDetailResponse>> loadDetailForPage(SalesOrderGroupPageQueryRequest request) {
        log.info("loadDetailForPage request:{}", JSON.toJSONString(request));
        SalesOrderAtomPageQueryRequest salesOrderAtomPageQueryRequest = new SalesOrderAtomPageQueryRequest();
        BeanUtils.copyProperties(request, salesOrderAtomPageQueryRequest);
        if (StringUtils.isBlank(salesOrderAtomPageQueryRequest.getOrderTag())) {
            salesOrderAtomPageQueryRequest.setOrderTag(SetOrderTag.NORMAL);
        }
        if (CollectionUtils.isEmpty(request.getSalesOrderTypeList())) {
            salesOrderAtomPageQueryRequest.setSalesOrderTypeList(SalesOrderTypeEnum.groupOrderCodes());
        } else {
            salesOrderAtomPageQueryRequest.setSalesOrderTypeList(request.getSalesOrderTypeList());
        }
        salesOrderAtomPageQueryRequest.setOrderCategoryCodeList(Lists.newArrayList(OrderCategoryEnum.GROUP.getCode(), OrderCategoryEnum.STOCK.getCode()));
        log.info("SalesOrderGroupServiceImpl#loadDetailForPage salesOrderAtomPageQueryRequest={}", JSON.toJSONString(salesOrderAtomPageQueryRequest));

        Result<List<ObtcSaleOrderLineIndex>> listResult = salesOrderAtomQueryService.detailListPage(salesOrderAtomPageQueryRequest, OrderCategoryEnum.GROUP.getCode());
        List<PageQuerySaleOrderDetailResponse> responseList = ObtcSaleOrderLineIndexToResponseConvertor.convert(listResult, OrderCategoryEnum.GROUP.getCode());
        Result<List<PageQuerySaleOrderDetailResponse>> result = Result.success(responseList, "", "");
        result.setTotal(listResult.getTotal());
        return result;
    }

    @FacadeInvoker(value = "一盘货销售订单修改", errorCode = "OC-01-001-01-16-013")
    @Override
    public Result<OrderBizUpdateResponse> update(OrderBizUpdateRequest request) {
        log.info("SalesOrderGroupServiceImpl#update request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + request.getSalesOrderNo();
        log.info("SalesOrderGroupServiceImpl#update lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#update 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            if (Objects.isNull(request.getCheckCredit())) {
                request.setCheckCredit(Boolean.TRUE);
            }
            if (Objects.isNull(request.getCheckStock())) {
                request.setCheckStock(Boolean.TRUE);
            }

            // 设置默认值
            request.setIsSubmit(Boolean.FALSE);
            request.setCheckCreditB(Boolean.FALSE);
            request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());

            OrderAtomUpdateResponse atomUpdateResponse = salesOrderBizUpdateService.update(request);

            OrderBizUpdateResponse bizUpdateResponse = new OrderBizUpdateResponse();
            BeanUtils.copyProperties(atomUpdateResponse, bizUpdateResponse);
            if (StringUtils.isNotBlank(bizUpdateResponse.getErrorCode())) {
                List<OrderLineAtomCreateResponse> orderDetails = atomUpdateResponse.getOrderDetails();
                if (CollectionUtils.isNotEmpty(orderDetails)) {
                    OrderLineAtomCreateResponse orderLineAtomCreateResponse = orderDetails.get(0);
                    return Result.fail(orderLineAtomCreateResponse.getErrorCode(), orderLineAtomCreateResponse.getMessage());
                }
                return Result.fail(atomUpdateResponse.getErrorCode(), atomUpdateResponse.getMessage());
            }

            // 发送MQ消息通知其他中心
            StopWatchUtils.start("订单中心商业修改", "sendSalesOrderChangeMsg");
            sendMsgService.sendSalesOrderChangeMsg(Lists.newArrayList(request.getSalesOrderNo()), InnerMessageEventEnum.SALES_ORDER_UPDATED);
            StopWatchUtils.stop();
            return Result.success(bizUpdateResponse, "", "");
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#update error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#update");
        }
    }

    @FacadeInvoker(value = "一盘货销售订单修改", errorCode = "OC-01-001-01-16-013")
    @Override
    public Result<OrderBizUpdateResponse> updateWithBeforeDelivery(OrderBizUpdateRequest request) {
        log.info("SalesOrderGroupServiceImpl#updateWithBeforeDelivery request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + request.getSalesOrderNo();
        log.info("SalesOrderGroupServiceImpl#updateWithBeforeDelivery lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#updateWithBeforeDelivery 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }

            if (Objects.isNull(request.getCheckCredit())) {
                request.setCheckCredit(Boolean.TRUE);
            }
            if (Objects.isNull(request.getCheckStock())) {
                request.setCheckStock(Boolean.TRUE);
            }

            // 设置默认值
            request.setIsSubmit(Boolean.FALSE);
            request.setCheckCreditB(Boolean.FALSE);
            request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());

            OrderAtomUpdateResponse atomUpdateResponse = salesOrderBizUpdateService.updateWithBeforeDelivery(request);

            OrderBizUpdateResponse bizUpdateResponse = new OrderBizUpdateResponse();
            BeanUtils.copyProperties(atomUpdateResponse, bizUpdateResponse);
            if (StringUtils.isNotBlank(bizUpdateResponse.getErrorCode())) {
                List<OrderLineAtomCreateResponse> orderDetails = atomUpdateResponse.getOrderDetails();
                if (CollectionUtils.isNotEmpty(orderDetails)) {
                    OrderLineAtomCreateResponse orderLineAtomCreateResponse = orderDetails.get(0);
                    return Result.fail(orderLineAtomCreateResponse.getErrorCode(), orderLineAtomCreateResponse.getMessage());
                }
                return Result.fail(atomUpdateResponse.getErrorCode(), atomUpdateResponse.getMessage());
            }

            // 发送MQ消息通知其他中心
            StopWatchUtils.start("订单中心商业修改", "sendSalesOrderChangeMsg");
            sendMsgService.sendSalesOrderChangeMsg(Lists.newArrayList(request.getSalesOrderNo()), InnerMessageEventEnum.SALES_ORDER_UPDATED);
            StopWatchUtils.stop();
            return Result.success(bizUpdateResponse, "", "");
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#updateWithBeforeDelivery error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#updateWithBeforeDelivery");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单同步创建", errorCode = "OC-01-001-01-16-006")
    public Result<OrderAtomCreateResponse> create(SalesOrderBizCreateRequest request) {
        AssertUtils.isTrue(StringUtils.isBlank(request.getReqNo()), "OC-01-001-01-15-001", "请求编码");
        log.info("SalesOrderGroupServiceImpl#create request={}", JSON.toJSONString(request));
        String lockKey = SALES_ORDER_GROUP_PREFIX + request.getReqNo();
        log.info("SalesOrderGroupServiceImpl#create lockKey={}", lockKey);
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, SLEEP_MILLIS)) {
            if (!lock.lock()) {
                log.error("SalesOrderGroupServiceImpl#create 分布式锁获取失败 lockKey={}", lockKey);
                return Result.fail("OC-00-000-01-99-002", "分布式锁获取失败");
            }
            // 移除入参里的前后空格
            StopWatchUtils.start("订单中心一盘货销售订单同步创建", "removeSpace");
            TrimUtils.removeSpace(request);
            StopWatchUtils.stop();

            StopWatchUtils.start("订单中心一盘货销售订单同步创建", "paramsInvalidCheck");
            AssertUtils.lengthCheck(request.getReqNo(), 128, true, "OC-01-001-01-15-004", "请求编码");
            AssertUtils.isTrue(Objects.isNull(request), "OC-01-001-01-15-001", "单据列表");
            // 设置订单类别编码缺省值：200集团
            request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
            request.setOrderCategoryName(OrderCategoryEnum.GROUP.getDesc());

            if (StringUtils.isBlank(request.getFulfillmentTypeCode())) {
                request.setFulfillmentTypeCode(FulfillmentTypeEnum.EXTERNAL_TO_EXTERNAL.getCode());
            }
            if (StringUtils.isNotBlank(request.getFromSys())) {
                request.setFromSys(request.getFromSys());
            }
            if (StringUtils.isNotBlank(request.getBusinessType())) {
                request.setBusinessType(request.getBusinessType());
            }
            if (StringUtils.isNotBlank(request.getBusinessUnitCode())) {
                request.setBusinessUnitCode(request.getBusinessUnitCode());
            }
            if (StringUtils.isBlank(request.getFulfillmentPriority())) {
                request.setFulfillmentPriority(FulfillmentPriorityEnum.NORMAL.getCode());
            }
            if (StringUtils.isBlank(request.getAutoFulfillment())) {
                request.setAutoFulfillment(Boolean.TRUE.toString());
            }
            if (Objects.isNull(request.getCheckCredit())) {
                request.setCheckCredit(Boolean.TRUE);
            }
            if (Objects.isNull(request.getCheckStock())) {
                request.setCheckStock(Boolean.TRUE);
            }
            if (Objects.isNull(request.getIsSubmit())) {
                request.setIsSubmit(Boolean.TRUE);
            }
            // 设置默认值
            request.setCheckCreditB(Boolean.FALSE);
            List<SalesOrderBizCreateRequest> salesOrderBizCreateRequestList = Lists.newArrayList(request);
            salesOrderGroupCreateParamsCheck.paramsInvalidCheck(salesOrderBizCreateRequestList, new ArrayList<>());
            StopWatchUtils.stop();
            // 组装同步创建入参
            SalesOrderBizBatchCreateRequest createRequest = new SalesOrderBizBatchCreateRequest();
            createRequest.setReqNo(request.getReqNo());
            createRequest.setBusinessType(request.getBusinessType());
            createRequest.setBusinessUnitCode(request.getBusinessUnitCode());
            createRequest.setFromSys(request.getFromSys());
            createRequest.setOrderList(salesOrderBizCreateRequestList);
            List<OrderAtomCreateResponse> createResponses = salesOrderBizCreateService.batchCreate(createRequest);
            OrderAtomCreateResponse orderAtomCreateResponse = createResponses.get(0);
            if (StringUtils.isNotBlank(orderAtomCreateResponse.getErrorCode())) {
                return Result.fail(orderAtomCreateResponse, orderAtomCreateResponse.getErrorCode(), orderAtomCreateResponse.getMessage());
            }
            return Result.success(orderAtomCreateResponse, "", "");
        } catch (Exception e) {
            log.error("SalesOrderGroupServiceImpl#create error", e);
            throw e;
        } finally {
            StopWatchUtils.print("SalesOrderGroupServiceImpl#create");
        }
    }

    @Override
    @FacadeInvoker(value = "一盘货销售订单明细批量查询", errorCode = "OC-01-003-01-16-008")
    public Result<List<PageQuerySaleOrderDetailResponse>> loadDetailForPageInner(SalesOrderGroupDetailPageRequest request) {
        SalesOrderAtomPageQueryRequest salesOrderAtomPageQueryRequest = JSON.parseObject(JSON.toJSONString(request), SalesOrderAtomPageQueryRequest.class);
        salesOrderAtomPageQueryRequest.setOrderTag(SetOrderTag.NORMAL);
        salesOrderAtomPageQueryRequest.setIsClose("0");
        if (CollectionUtils.isEmpty(request.getSalesOrderTypeList())) {
            salesOrderAtomPageQueryRequest.setSalesOrderTypeList(SalesOrderTypeEnum.groupOrderCodes());
        } else {
            salesOrderAtomPageQueryRequest.setSalesOrderTypeList(request.getSalesOrderTypeList());
        }
        if (StringUtils.isBlank(salesOrderAtomPageQueryRequest.getOrderCategoryCode())) {
            salesOrderAtomPageQueryRequest.setOrderCategoryCodeList(Lists.newArrayList(OrderCategoryEnum.GROUP.getCode(), OrderCategoryEnum.STOCK.getCode()));
        }
        Result<List<ObtcSaleOrderLineIndex>> listResult = salesOrderAtomQueryService.detailListPageInner(salesOrderAtomPageQueryRequest);
        if (Objects.nonNull(listResult) && listResult.isSuccess()) {
            List<ObtcSaleOrderLineIndex> esList = listResult.getResult();
            if (CollectionUtils.isNotEmpty(esList)) {
                QueryOrderLineByIdListRequest queryOrderLineByIdListRequest = QueryOrderLineByIdListRequest.builder().ids(esList.stream().map(ObtcSaleOrderLineIndex::getSubId).collect(Collectors.toList())).build();
                QueryOrderLineByIdListResponse queryOrderLineByIdListResponse = orderLineService.queryOrderLineByIdList(queryOrderLineByIdListRequest);
                List<OrderLine> dbLineList = queryOrderLineByIdListResponse.getResult();
                if (CollectionUtils.isNotEmpty(dbLineList)) {
                    Map<Long, OrderLine> dbLineMap = dbLineList.stream().collect(Collectors.toMap(key -> key.getId(), Function.identity()));
                    for (ObtcSaleOrderLineIndex obtcSaleOrderLineIndex : esList) {
                        OrderLine orderLine = dbLineMap.get(obtcSaleOrderLineIndex.getSubId());
                        if (Objects.nonNull(orderLine)) {
                            obtcSaleOrderLineIndex.setSubCumulativeNoticeQuantity(orderLine.getCumulativeNoticeQuantity());
                            obtcSaleOrderLineIndex.setSubProductationTime(orderLine.getProductationTime().getTime());
                            obtcSaleOrderLineIndex.setSubRefuseReasonCode(orderLine.getRefuseReasonCode());
                            obtcSaleOrderLineIndex.setSubRefuseReasonName(orderLine.getRefuseReasonName());
                        }
                    }
                }
            }
        }
        List<PageQuerySaleOrderDetailResponse> responseList = ObtcSaleOrderLineIndexToResponseConvertor.convert(listResult, OrderCategoryEnum.GROUP.getCode());
        Result<List<PageQuerySaleOrderDetailResponse>> result = Result.success(responseList, "", "");
        result.setTotal(listResult.getTotal());
        return result;
    }

    @Override
    public Result<List<PageQuerySaleOrderDetailResponse>> pageOrderDetail(SalesOrderAtomPageQueryRequest request) {
        request.setOrderTag(SetOrderTag.NORMAL);
        request.setSalesOrderTypeList(SalesOrderTypeEnum.groupOrderCodes());
        request.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
        request.setDetailStatusList(Lists.newArrayList(SalesOrderGroupStatusEnum.BEFORE_DELIVERY.getCode().toString(), SalesOrderGroupStatusEnum.PARTIAL_DELIVER.getCode().toString(), SalesOrderGroupStatusEnum.COMPLETED.getCode().toString()));
        log.info("SalesOrderGroupServiceImpl#pageOrderDetail request={}", JSON.toJSONString(request));
        Result<List<ObtcSaleOrderLineIndex>> listResult = salesOrderAtomQueryService.pageOrderDetail(request);
        List<PageQuerySaleOrderDetailResponse> responseList = ObtcSaleOrderLineIndexToResponseConvertor.convert(listResult, OrderCategoryEnum.GROUP.getCode());
        Result<List<PageQuerySaleOrderDetailResponse>> result = Result.success(responseList, "", "");
        result.setTotal(listResult.getTotal());
        return result;
    }

    @Override
    public Result<List<NoConfirmFrozenAmountsResponse>> noConfirmFrozenAmounts(NoConfirmFrozenAmountsRequest request) {
        long l1 = System.currentTimeMillis();
        OrderLineAdbRequest orderLineAdbRequest = new OrderLineAdbRequest();
        orderLineAdbRequest.setCustomerCodeList(request.getCustomerCodeList());
        orderLineAdbRequest.setStatusList(Lists.newArrayList(SalesOrderStatusEnum.BEFORE_DELIVERY.getCode().toString(), SalesOrderStatusEnum.PARTIAL_DELIVER.getCode().toString()));
        orderLineAdbRequest.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
        long l2 = System.currentTimeMillis();
        Result<List<OrderLineAdbResponse>> listResult = cbtcObtcOrderLineAdbService.summaryAmount(orderLineAdbRequest);
        long l3 = System.currentTimeMillis();
        log.info("noConfirmFrozenAmounts orderLineAdbRequest:{}; listResult:{}", JSON.toJSONString(orderLineAdbRequest), JSON.toJSONString(listResult));
        if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
            return Result.success(Lists.newArrayList());
        }
        List<NoConfirmFrozenAmountsResponse> responses = new ArrayList<>();
        Map<String, List<OrderLineAdbResponse>> listMap = listResult.getResult().stream().collect(Collectors.groupingBy(OrderLineAdbResponse::getCustomerCode));
        for (Map.Entry<String, List<OrderLineAdbResponse>> entry : listMap.entrySet()) {
            NoConfirmFrozenAmountsResponse response = new NoConfirmFrozenAmountsResponse();
            response.setCustomerCode(entry.getKey());
            BigDecimal noConfirmFrozenAmounts = new BigDecimal(0);
            for (OrderLineAdbResponse orderLineAdbResponse : entry.getValue()) {
                if (Objects.nonNull(orderLineAdbResponse.getAmounts())) {
                    noConfirmFrozenAmounts = noConfirmFrozenAmounts.add(orderLineAdbResponse.getAmounts());
                }
            }
            response.setNoConfirmFrozenAmounts(noConfirmFrozenAmounts.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString());
            responses.add(response);
        }
        log.info("noConfirmFrozenAmounts responses:{}", JSON.toJSONString(responses));
        long l4 = System.currentTimeMillis();
        log.info("noConfirmFrozenAmounts totalTIme:{}; queryADBTime:{}", l4 - l1, l3 - l2);
        return Result.success(responses);
    }

}
